//判断等式是否成功
import { create, all } from 'mathjs';
// 配置 math.js 使用 Decimal 类型
const math = create(all, {
  number: 'BigNumber', // 使用 BigNumber 类型
});
//判断等式是否成功
export const count = (expression: string, precision: number = 4, isRoundOff: boolean = false) => {
  try {
    // 使用 Function 构造器代替 eval，以避免直接执行任意代码带来的风险
    // 注意：这仍然需要对输入进行严格的验证和清理
    const _count = math.evaluate(expression);
    return isRoundOff ? Number(_count.toFixed(precision)) : truncateToTwoDecimalsWithTrick(_count, precision);
  } catch (e) {
    ElMessage.error('无效的表达式');
    return null;
  }
};
//截断
export const truncateToTwoDecimalsWithTrick = (number: number, precision: number = 2) => {
  const fixedString = number.toString().includes('.') ? number.toString().split('.')[0] + '.' + number.toString().split('.')[1].slice(0, precision) : number.toString();
  return parseNumber(fixedString);
};
// 定义接口
interface TaxCalculation {
  taxRate: string; // 税率
  taxExcludedUnitPrice: string; // 未税单价
  taxIncludedUnitPrice: string; // 含税单价
  taxExcludedTotalPrice?: string; // 未税总价
  taxIncludedTotalPrice?: string; // 含税总价
  quantity?: string; // 数量
}
const taxKeyObj = {
  taxRate: 'taxRate', // 税率
  taxExcludedUnitPrice: 'taxExcludedUnitPrice', // 未税单价
  taxIncludedUnitPrice: 'taxIncludedUnitPrice', // 含税单价
  taxExcludedTotalPrice: 'taxExcludedTotalPrice', // 未税总价
  taxIncludedTotalPrice: 'taxIncludedTotalPrice', // 含税总价
  quantity: 'quantity', // 数量
};
/**
 * 根据税率重新计算未税单价或含税单价，并更新总价
 */
export const setTaxRate = (row: any, taxKey: TaxCalculation = taxKeyObj): void => {
  const { taxRate, taxExcludedUnitPrice, taxIncludedUnitPrice } = taxKey;

  const currentTaxRate = getTaxRate(row, taxRate);

  // 获取当前行中的含税单价和未税单价值
  const includedPrice = parseNumber(row[taxIncludedUnitPrice]);
  const excludedPrice = parseNumber(row[taxExcludedUnitPrice]);

  // 如果两者都为空，则不处理
  if (isNaN(includedPrice) && isNaN(excludedPrice)) {
    return;
  }

  // 根据是否有含税单价决定如何计算
  if (!isNaN(includedPrice)) {
    // 含税价存在 → 推导未税价
    row[taxExcludedUnitPrice] = count(`${includedPrice} / (1 + ${currentTaxRate})`, 9);
  } else if (!isNaN(excludedPrice)) {
    // 未税价存在 → 推导含税价
    row[taxIncludedUnitPrice] = count(`${excludedPrice} * (1 + ${currentTaxRate})`, 9);
  }

  // 统一调用一次总价计算
  setTaxTotalPrice(row, taxKey);
};

//修改-数量
export const setTaxQuantity = (row: any, taxKey: TaxCalculation = taxKeyObj) => {
  // 统一调用一次总价计算
  setTaxTotalPrice(row, taxKey);
};
/**
 * 修改未税单价后，更新含税单价，并更新总价
 */
export const setTaxExcludedUnitPrice = (row: any, taxKey: TaxCalculation = taxKeyObj): void => {
  const { taxRate, taxExcludedUnitPrice, taxIncludedUnitPrice } = taxKey;

  // 获取税率
  const rate = getTaxRate(row, taxRate);

  // 获取未税单价数值
  const excludedPrice = parseNumber(row[taxExcludedUnitPrice]);
  if (isNaN(excludedPrice) || excludedPrice < 0) return;

  // 计算含税单价：未税单价 * (1 + 税率)
  const includedPrice = count(`${excludedPrice} * (1 + ${rate})`, 9);

  // 更新行数据
  row[taxIncludedUnitPrice] = includedPrice;

  // 更新总价
  setTaxTotalPrice(row, taxKey);
};

/**
 * 修改含税单价后，更新未税单价，并更新总价
 */
export const setTaxInclusiveUnitPrice = (row: any, taxKey: TaxCalculation = taxKeyObj): void => {
  const { taxRate, taxExcludedUnitPrice, taxIncludedUnitPrice } = taxKey;

  // 获取税率
  const rate = getTaxRate(row, taxRate);

  // 获取含税单价数值
  const includedPrice = parseNumber(row[taxIncludedUnitPrice]);
  if (isNaN(includedPrice) || includedPrice < 0) return;

  // 计算未税单价：含税单价 / (1 + 税率)
  const excludedPrice = count(`${includedPrice} / (1 + ${rate})`, 9);

  // 更新行数据
  row[taxExcludedUnitPrice] = excludedPrice;

  // 更新总价
  setTaxTotalPrice(row, taxKey);
};
/**
 * 修改未税总价后，更新未税单价，并联动更新含税价及总价
 */
export const setTaxExclusiveTotalPrice = (row: any, taxKey: TaxCalculation = taxKeyObj): void => {
  const { taxExcludedUnitPrice, taxExcludedTotalPrice, quantity } = taxKey;

  // 校验必要字段是否存在
  if (!taxExcludedUnitPrice || !taxExcludedTotalPrice || !quantity) {
    return;
  }

  // 获取数值
  const totalPrice = parseNumber(row[taxExcludedTotalPrice]);
  const qty = parseNumber(row[quantity]);

  // 如果总价或数量无效，则返回
  if (isNaN(totalPrice) || isNaN(qty) || qty <= 0) {
    return;
  }

  // 计算未税单价：未税总价 / 数量
  const unitPrice = count(`${totalPrice} / ${qty}`, 9);

  // 更新未税单价
  row[taxExcludedUnitPrice] = unitPrice;

  // 联动更新含税单价和其他价格
  setTaxExcludedUnitPrice(row, taxKey);
};
/**
 * 修改含税总价后，更新含税单价，并联动更新未税价及总价
 */
export const setTaxInclusiveTotalPrice = (row: any, taxKey: TaxCalculation = taxKeyObj): void => {
  const { taxIncludedUnitPrice, taxIncludedTotalPrice, quantity } = taxKey;

  // 校验必要字段是否存在
  if (!taxIncludedUnitPrice || !taxIncludedTotalPrice || !quantity) {
    return;
  }

  // 获取数值
  const totalPrice = parseNumber(row[taxIncludedTotalPrice]);
  const qty = parseNumber(row[quantity]);

  // 如果总价或数量无效，则返回
  if (isNaN(totalPrice) || isNaN(qty) || qty <= 0) {
    return;
  }

  // 计算含税单价：含税总价 / 数量
  const unitPrice = count(`${totalPrice} / ${qty}`, 9);

  // 更新含税单价
  row[taxIncludedUnitPrice] = unitPrice;

  // 联动更新未税单价和其他价格
  setTaxInclusiveUnitPrice(row, taxKey);
};
/**
 * 获取税率并标准化为小数格式（例如：13 → 0.13，0.13 → 0.13）
 * @param row 数据行对象
 * @param key 税率字段名（可选）
 * @returns 标准化的税率（小数）
 */
export const getTaxRate = (row: any, key?: string): number => {
  // 如果没有提供 key 或对应字段不存在，则默认返回 0
  if (!key || !(key in row)) {
    return 0;
  }

  // 获取原始税率值
  let rawRate = row[key];

  // 清理输入：如果是字符串，尝试去除非法字符并转为数字
  if (typeof rawRate === 'string') {
    rawRate = parseNumber(rawRate.replace(/[^\d.-]/g, ''));
  } else {
    rawRate = Number(rawRate);
  }

  // 如果不是有效数字，返回 0
  if (isNaN(rawRate)) {
    return 0;
  }

  // 判断当前税率是否是“整数百分比”，如 13 表示 13%，即 0.13
  if (rawRate > 1) {
    return rawRate / 100;
  }

  // 否则直接返回原值（如 0.13）
  return rawRate;
};
/**
 * 根据单价和数量重新计算未税总价和含税总价
 */
export const setTaxTotalPrice = (row: any, taxKey: TaxCalculation = taxKeyObj): void => {
  const { taxExcludedUnitPrice, taxIncludedUnitPrice, taxExcludedTotalPrice, taxIncludedTotalPrice, quantity } = taxKey;

  // 必要字段检查
  if (!taxExcludedUnitPrice || !taxIncludedUnitPrice || !taxExcludedTotalPrice || !taxIncludedTotalPrice || !quantity) {
    return;
  }

  // 获取数值
  const excludedPrice = parseNumber(row[taxExcludedUnitPrice]);
  const includedPrice = parseNumber(row[taxIncludedUnitPrice]);
  const qty = parseNumber(row[quantity]);

  // 如果单价或数量无效，则返回
  if (isNaN(excludedPrice) || isNaN(includedPrice) || isNaN(qty)) {
    return;
  }

  // 避免除以零或负数
  if (qty <= 0) {
    row[taxExcludedTotalPrice] = 0;
    row[taxIncludedTotalPrice] = 0;
    return;
  }

  // 计算总价（保留两位小数）
  const excludedTotal = count(`${excludedPrice} * ${qty}`, 2);
  const includedTotal = count(`${includedPrice} * ${qty}`, 2);

  // 更新数据
  row[taxExcludedTotalPrice] = excludedTotal;
  row[taxIncludedTotalPrice] = includedTotal;
};

/**
 * 根据含税总价和税率计算税额
 * @param row 包含数据行的对象
 * @param taxKey 配置对象，包含字段名：含税总价字段、税率字段
 * @returns number 返回计算后的税额（保留两位小数）
 */
export const calculateTaxFromInclusiveTotalPrice = (row: any, taxKey: TaxCalculation = taxKeyObj): number => {
  // 从配置中解构出关键字段名称
  const { taxIncludedTotalPrice: totalPriceKey, taxRate: taxRateKey } = taxKey;

  // 如果必要字段未定义，直接返回 0 并提示错误
  if (!totalPriceKey || !taxRateKey) {
    console.warn('[calculateTaxFromInclusiveTotalPrice] 缺少必要字段配置');
    return 0;
  }

  // 获取含税总价的值，并转换为数字
  const totalPrice = parseNumber(row[totalPriceKey]);

  // 获取税率（自动处理百分比格式，如 13 → 0.13）
  const taxRate = getTaxRate(row, taxRateKey);

  // 如果数值无效，则返回 0
  if (isNaN(totalPrice) || isNaN(taxRate) || taxRate < 0) {
    return 0;
  }

  // 计算税额：含税价 - 不含税价（即：含税价 × 税率 ÷ (1 + 税率)）
  const taxAmount = totalPrice - totalPrice / (1 + taxRate);

  // 返回保留两位小数的结果
  return parseNumber(taxAmount.toFixed(2));
};

/**
 * 将数字金额转换为中文大写（人民币格式）
 * 示例：123.45 -> 壹佰贰拾叁元肆角伍分
 *       123   -> 壹佰贰拾叁元整
 */
export const chineseNumber = (amount: number): string => {
  // 中文数字映射表
  const CN_NUMS = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
  // 整数部分单位
  const CN_INT_RADICES = ['', '拾', '佰', '仟'];
  const CN_INT_UNITS = ['', '万', '亿', '兆']; // 单位层级
  // 小数部分单位
  const CN_DEC_UNITS = ['角', '分'];
  // 最大支持数值
  const MAX_NUMBER = 999999999999.99;

  // 边界检查
  if (amount < 0 || amount > MAX_NUMBER) {
    console.error('参数错误：金额超出范围');
    return '';
  }

  // 处理整数和小数部分
  const integerPart = Math.floor(amount);
  const decimalPart = Math.round((amount - integerPart) * 100); // 避免浮点误差

  let result = '';

  // 一、处理整数部分
  if (integerPart === 0) {
    result = CN_NUMS[0];
  } else {
    const intStr = String(integerPart);
    const len = intStr.length;
    let zeroCount = 0; // 连续零计数
    let lastUnitEmpty = true; // 上一级单位是否为空

    for (let i = 0; i < len; i++) {
      const n = +intStr[i];
      const position = len - i - 1;
      const level = Math.floor(position / 4); // 当前是第几级单位（亿、万、个）
      const innerPos = position % 4; // 当前单位在组内的位置（千百十）

      const radix = CN_INT_RADICES[innerPos];
      const unit = CN_INT_UNITS[level];

      if (n === 0) {
        zeroCount++;
        lastUnitEmpty = false;
        continue;
      }

      // 添加中间多余的“零”
      if (zeroCount > 0 && !lastUnitEmpty) {
        result += CN_NUMS[0];
        zeroCount = 0;
      }

      result += CN_NUMS[n] + radix;
      lastUnitEmpty = false;

      // 添加万、亿、兆等大单位
      if (innerPos === 0) {
        result += unit;
        lastUnitEmpty = true;
      }
    }

    result += '元';
  }

  // 二、处理小数部分
  if (decimalPart === 0) {
    result += '整';
  } else {
    const decStr = decimalPart.toString().padStart(2, '0'); // 确保两位
    for (let i = 0; i < decStr.length && i < CN_DEC_UNITS.length; i++) {
      const digit = +decStr[i];
      if (digit !== 0) {
        result += CN_NUMS[digit] + CN_DEC_UNITS[i];
      }
    }
  }

  return result;
};

/**
 * 格式化数字为千分位形式，默认保留两位小数（四舍五入）
 */
export const formatThousandSeparator = (num: number | string): string => {
  // 统一处理输入，防止非数字
  const number = parseNumber(num);

  if (isNaN(number)) {
    return '';
  }

  // 先转为保留两位小数的数值（四舍五入）
  const fixedNumber = Math.round(number * 100) / 100;

  // 使用 toLocaleString 格式化千分位
  return fixedNumber.toLocaleString('en-US', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  });
};
const parseNumber = (value: any): number => {
  if (typeof value === 'number') return value;
  if (typeof value !== 'string') return NaN;
  const cleaned = value.replace(/[^\d.-]/g, '');
  return isNaN(parseFloat(cleaned)) ? NaN : parseFloat(cleaned);
};
